#pragma once

#include <iostream>
#include <vector>
#include <pthread.h>
#include <functional>
#include <sys/types.h>
#include <sys/socket.h>
#include "Lockgarud.hpp"
#include "InetAddr.hpp"
#include "ThreadPool.hpp"

using task_t = std::function<void()>;

class MessageRoute
{
private:
	bool Isexists(const InetAddr &user)
	{
		for (auto u : _onlin_user)
		{
			if (u == user)
			{
				return true;
			}
		}
		return false;
	}

public:
	MessageRoute()
	{
		pthread_mutex_init(&_mutex, nullptr);
	}

	void Adduser(const InetAddr &user)
	{
		LockGuard lock(&_mutex);
		if (Isexists(user))
		{
			return;
		}

		_onlin_user.push_back(user);
	}

	void Deleuser(const InetAddr &user)
	{
		LockGuard lock(&_mutex);
		for (auto iter = _onlin_user.begin(); iter != _onlin_user.end(); iter++)
		{
			if (*iter == user)
			{
				_onlin_user.erase(iter);
				break;
			}
		}
	}

	void RouteHeleper(int sockfd, std::string messages, InetAddr who)
	{
		LockGuard lock(&_mutex);
		// 2.进行消息转发,转发所有用户的消息
		for (auto u : _onlin_user)
		{
			std::string send_messages = "\n[" + who.ip() + ":" + std::to_string(who.port()) + "]#" + messages + "\n";
			struct sockaddr_in clientaddr = u.Addr();
			sendto(sockfd, send_messages.c_str(), send_messages.size(), 0, (struct sockaddr *)&clientaddr, sizeof(clientaddr));
		}
	}

	void Route(int sockfd, std::string messages, InetAddr who)
	{
		// 1.首先如果用户不存在要先添加用户信息
		Adduser(who);

		// 1.1 如果客户端要退出，就要把用户从列表中删除
		if (messages == "Q" || messages == "QUIT")
		{
			Deleuser(who);
		}

		task_t t = std::bind(&MessageRoute::RouteHeleper, this, sockfd, messages, who);
		threadpool_t<task_t>::GetInstance()->Enqueue(t);
	}

	~MessageRoute()
	{
		pthread_mutex_destroy(&_mutex);
	}

private:
	std::vector<InetAddr> _onlin_user; // 用户列表
	pthread_mutex_t _mutex;
};